// ImageView.cpp : implementation of the CImageView class
//

#include "stdafx.h"
#include "SpriteTool.h"
#include "ChildFrm.h"
#include "SpriteDoc.h"
#include "ImageView.h"
#include "LeftView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CImageView

IMPLEMENT_DYNCREATE(CImageView, CScrollView)

BEGIN_MESSAGE_MAP(CImageView, CScrollView)
	//{{AFX_MSG_MAP(CImageView)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_MOUSEWHEEL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImageView construction/destruction

CImageView::CImageView()
{
	m_pSelect = NULL;

	IMG_CX = 64;
	IMG_CY = 64;
	TXT_CX = 64;
	TXT_CY = 20;
	IND_X = 16;
	IND_Y = 12;

}

CImageView::~CImageView()
{
}

BOOL CImageView::PreCreateWindow(CREATESTRUCT& cs)
{
	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CImageView drawing

static inline void ResizeOf(int& nWidth, int& nHeight, const int lWidth, const int lHeight)
{
	const float fWIDTH = (const float)lWidth;
	const float fHEIGHT = (const float)lHeight;

	if(nWidth > lWidth|| nHeight > lHeight)
	{
		float f = 1.0f;
		if(nWidth > nHeight)
		{
			f = fWIDTH/(float)nWidth;
		}
		else
		{
			f = fHEIGHT/(float)nHeight;
		}

		nWidth = (int)((float)nWidth*f);
		nHeight = (int)((float)nHeight*f);
	}
}

void CImageView::OnDraw(CDC* pDC)
{
	CSpriteDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CSize tSize = GetTotalSize();

	RECT rClient;
	GetClientRect(&rClient);
	if(tSize.cx < rClient.right)
	{
		tSize.cx = rClient.right;
	}

	int x = IND_X;
	int y = IND_Y;

	list<GROUP*>::iterator it;
	it = pDoc->m_Groups.begin();
	while(it != pDoc->m_Groups.end())
	{
		GROUP* pGroup = *it++;

		pGroup->rect.left = x;
		pGroup->rect.top = y;
		pGroup->rect.right = x + TXT_CX;
		pGroup->rect.bottom = y + TXT_CY;

		pDC->TextOut(x, y, pGroup->szName);
		pDC->DrawText(pGroup->szName, &(pGroup->rect), DT_LEFT);

		y += TXT_CY;

		if(pGroup->bExpand == TRUE)
		{
			list<IMAGE*>::iterator lit;
			lit = pGroup->ImgList.begin();
			while(lit != pGroup->ImgList.end())
			{
				IMAGE* pImage = *lit++;

				if(pImage->nType == SceneDat::eImage)
				{
					int cx = pImage->xImage.GetWidth();
					int cy = pImage->xImage.GetHeight();

					int w = cx;
					int h = cy;

					ResizeOf(cx, cy, IMG_CX, IMG_CY);

					pImage->rect.left = x;
					pImage->rect.top = y;
					pImage->rect.right = x + IMG_CX;
					pImage->rect.bottom = y + IMG_CY;

					if(m_pSelect == pImage)
					{
						pDC->Rectangle(&(pImage->rect));
					}

					int fx = (IMG_CX - cx)/2;
					int fy = (IMG_CY - cy)/2;

					if(w > IMG_CX || h > IMG_CY)
					{
						pImage->xImage.Draw2(pDC->GetSafeHdc(), x + fx, y + fy, cx, cy);
					}
					else
					{
						pImage->xImage.Draw(pDC->GetSafeHdc(), x + fx, y + fy);
					}
				}

				y +=  IMG_CY + IND_Y;
			}
		}

		x += IMG_CX + IND_X;
		y = IND_Y;
	}


}

void CImageView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CSpriteDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	if(pDoc->m_Groups.size() == 0)
	{
		OnLoadImages();
	}

	Resize();
}

void CImageView::Resize()
{
	CSize sizeTotal;
	sizeTotal.cx = sizeTotal.cy = 100;

	CSpriteDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	int nGroup = pDoc->m_Groups.size();

	int nMaxCount = 0;

	list<GROUP*>::iterator it;
	it = pDoc->m_Groups.begin();
	while(it != pDoc->m_Groups.end())
	{
		GROUP* pGroup = *it++;
		int nCount = pGroup->ImgList.size();
		if(nCount > nMaxCount)
			nMaxCount = nCount;
	}

	sizeTotal.cx += nGroup * (IMG_CX+IND_X);
	sizeTotal.cy += nMaxCount * (IMG_CY + IND_Y);
	
	SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CImageView diagnostics

#ifdef _DEBUG
void CImageView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CImageView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CSpriteDoc* CImageView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSpriteDoc)));
	return (CSpriteDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CImageView message handlers
UINT CImageView::HitTest(const CPoint& pt, CImageView::HITIT& refHit)
{
	CSpriteDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	const int INDENT = 10;
	const int LINE_Y = 10;

	int x = INDENT;
	int y = LINE_Y;

	CPoint ptHit = GetScrollPosition();
	ptHit.x += pt.x;
	ptHit.y += pt.y;

	list<GROUP*>::iterator it;
	it = pDoc->m_Groups.begin();
	while(it != pDoc->m_Groups.end())
	{
		GROUP* pGroup = *it++;

		if(PtInRect(&(pGroup->rect), ptHit))
		{
			refHit.pGroup = pGroup;
			return eGroup;
		}
		if(pGroup->bExpand == TRUE)
		{
			list<IMAGE*>::iterator lit;
			lit = pGroup->ImgList.begin();
			while(lit != pGroup->ImgList.end())
			{
				IMAGE* pImage = *lit++;

				if(PtInRect(&(pImage->rect), ptHit))
				{
					refHit.pImage = pImage;
					return eImage;
				}
			}
		}
	}
	return eNull;
}

void CImageView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	HITIT refHit;
	refHit.pHitit = NULL;
	
	UINT nHit = HitTest(point, refHit);
	if(nHit == eGroup)
	{
	}
	else if(nHit == eImage)
	{
		if(m_pSelect != refHit.pImage)
		{
			IMAGE* pOld = m_pSelect;
			m_pSelect = refHit.pImage;

			if(pOld)
			{
				InvalidateRect(&(pOld->rect));
				InvalidateRect(&(m_pSelect->rect), FALSE);
			}
			else
			{
				InvalidateRect(&(m_pSelect->rect), FALSE);
			}
		}
	}

	CScrollView::OnLButtonDown(nFlags, point);
}

void CImageView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	OnLButtonDown(nFlags, point);
	if(m_pSelect != NULL)
	{
		CString s("fclip\t");
		s += m_pSelect->pGroup->szName;
		s += "\t";
		s += m_pSelect->szName;
		s += "\t 0 0 0.0";

		CChildFrame* pFrameWnd = (CChildFrame*)GetParentFrame();
		if(pFrameWnd)
		{
			CLeftView* pLeftView = pFrameWnd->GetLeftView();
			pLeftView->OnAddFclip(s);
		}
	}
	
	CScrollView::OnLButtonDblClk(nFlags, point);
}

void CImageView::OnLoadImages() 
{
	CString szFilter;
	szFilter.LoadString(IDS_IMG_EXTS);

	CFileDialog FileDlg(TRUE, _T(".png"), NULL,
		OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST, szFilter);
		
	if (IDOK == FileDlg.DoModal())
	{
		CSpriteDoc* pDoc = GetDocument();

		CString szFolder = FileDlg.GetPathName();

		TCHAR szShort[MAX_PATH];
		GetShortPathName(szFolder, szShort, MAX_PATH);
		szFolder = szShort;

		if(!PathIsDirectory(szFolder))
		{
			LPCTSTR szFull = szFolder;
			LPCTSTR szFileName = PathFindFileName(szFolder);
			szFolder = CString(szFolder, szFileName-szFull);
		}

		int nGroup = pDoc->m_Groups.size();

		CString szGroup;
		szGroup.Format(_T("Group%d\t"), nGroup);
		szGroup += szFolder;

		GROUP* pGroup = pDoc->NewGroup(szGroup);

		if(pGroup)
		{
			POSITION pos = FileDlg.GetStartPosition();
			while (pos)
			{
				CString	szPathName = FileDlg.GetNextPathName(pos);
				LPCTSTR szFileName = PathFindFileName(szPathName);

				pGroup->AddImage(szFileName, szFolder);				
			}
			Resize();
			Invalidate();
		}
	}
}

BOOL CImageView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	CPoint pts = GetScrollPosition();
	pts.y -= zDelta;
	ScrollToPosition(pts);
	
	return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
}
